//
// files.h
// libprotea
// Tools Library for the Protea Project / File management functionality
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
// 
// Please send correspondence to:
// 
// theproteaproject@gmail.com
//

#ifndef __PROTEA_FILES_H__
#define __PROTEA_FILES_H__

/**
	\file files.h
	\brief OS independent routines to manipulate files (Copy, Delete, Rename)
*/

#include "transport.h"

const long FILE_BUFFER_SIZE = 4096;
void DumpMemory( char* data, int count );

/**
	\brief Deletes a file
	\param filename Full filename of the file to delete
	Deletes a file
*/
extern __EXPORT int XCDeleteFile( const char* filename );

/**
	\brief Copys a file
	\param source Full filename of the file to copy
	\param dest Full filename of the file to copy over
	Copys a file
*/
extern __EXPORT int XCCopyFile( const char* source, const char* dest );

/**
	\brief Renames a file
	\param source Full filename of the file to rename
	\param dest Full filename of the new file
	Renames a file
*/
extern __EXPORT int XCRenameFile( const char* source, const char* dest );

/**
	\brief Determines whether a file exists
	\param filename Full filename of the file to check
	Determines whether a file exists

	Returns true or false
*/
extern __EXPORT bool XCFileExists( const char* filename );

enum eFileAccess {
	none = 0,
	read_only = OSDEP_READ_ONLY,
	write_only = OSDEP_WRITE_ONLY,
	read_write = OSDEP_READ_WRITE
};

enum eFileMode {
	create_new = OSDEP_CREATE_NEW,
	create_always = OSDEP_CREATE_ALWAYS,
	open_existing = OSDEP_OPEN_EXISTING,
	open_always = OSDEP_OPEN_ALWAYS
};

enum eFileSeekMode {
	seek_start = OSDEP_SEEK_START,
	seek_current = OSDEP_SEEK_CURRENT,
	seek_end = OSDEP_SEEK_END
};

class __EXPORT XCFileTransport : public XCTransport {
public:
	XCFileTransport( XCAppInterface* appowner, XCMsgPort* portowner = NULL );
	virtual ~XCFileTransport();

	void Open( const char* filename, eFileAccess readwrite = read_only, eFileMode mode = open_existing );
	bool Eof();

	virtual int Send( const void* data, int size = -1 );
	virtual int Recv( void* data, int size );
	virtual int Close();

	/// Cancel outstanding Async I/O requests
	virtual void CancelIO();

	virtual PORT_HANDLE GetInHandle();
	virtual PORT_HANDLE GetOutHandle();

	void Seek( long location, eFileSeekMode mode = seek_start );
	long GetPos();
	long GetSize();
	void Flush();
	void Lock();
	void Unlock();
protected:
	PORT_HANDLE file;
	bool dirty_cache;
	long inleft;
	long instart;
	char* inbuffer;
	long outstart;
	long outused;
	char* outbuffer;
	bool eof_flag;
};

#endif
